package com.umpay.util;


import com.umpay.business.ebankpay.impl.EbankPayBusinessImpl;
import com.umpay.dict.retcode.MerAccessEC;
import com.umpay.exception.BusinessException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
/**
 * 
 * @ClassName: ReqParaCheckUtil  
 * @Description: 校验参数  
 * @author zhangtao  
 * @date May 26, 2018
 */
public class ReqParaCheckUtil {
    /**
     * Logger for this class
     */
	private static final Logger log = LoggerFactory.getLogger(EbankPayBusinessImpl.class);
    

	/**
	 * @方法名: checkRequireAndRegular  
	 * @功能描述: 校验请求参数的完整性，以及各参数的正则表达式，配置文件在regex.properties
	 * @param reqMap 请求参数
	 * @param rule 获取参数完整性规则，在配置文件中对应的key
	 * @param prefix 获取参数正则表达式是，在配置文件中对应的key的前缀
	 * @throws BusinessException
	 */
	public static void checkRequireAndRegular(Map<String,String> reqMap, String rule) throws BusinessException{
		PropertyUtil propertyUtil = (PropertyUtil)SpringUtil.getBean("propertyUtil");
		// 找到这个服务需要校验哪些字段
	    String keys = propertyUtil.getProperty(rule);
	    log.info(String.format("【参数校验】开始校验参数完整性,规则：[%s]=%s",rule,keys));
		if (StringUtil.isEmpty(keys)) {
			log.info(String.format("【参数校验】Service %s found no check info", rule));
		    return;
		}
		// 对每个key进行正则表达式校验
		String[] chkKeys = StringUtil.split(keys, ",");
		for (String key : chkKeys) {
          doCheck(key, reqMap);
		}
		log.info("校验参数成功");
	}


   /**
    * @方法名: doCheck  
    * @功能描述: 校验
    * @param key
    * @param reqMap
    * @param prefix
    * @throws BusinessException
    */
   protected static  void doCheck(String key, Map<String,String> reqMap) throws BusinessException {
       if (StringUtil.isEmpty(key)) {
           return;
       }
       if (isOptional(key)) {
           check(removBrackets(key), reqMap, false);
       } else {
           check(key, reqMap, true);
       }
   }

   /**
    * 去除中括号 
    * @param key 待校验的Key
    * @return 去除中括号的字符串
    */
   private static String removBrackets(String key) {
       return key.substring(1, key.length() - 1);
   }

   /**
    * 是否是必须的字段 
    * @param key 待校验的Key
    * @return 必须字段返回<tt>true</tt>, 否则返回<tt>false</tt>
    */
   private static boolean isOptional(String key) {
       return key.startsWith("[") && key.endsWith("]");
   }

   /**
    * 真正的校验逻辑，通过配置的正则表达式校验字段是否符合规范
    * 
    * @param key
    *            待校验字段和需要放入到DC的目标字段
    * @param dc
    * @param must
    *            字段是否是必须的
    * @throws Exception
    */
   protected static void check(String key, Map<String,String> reqMap, boolean must) throws BusinessException {

       String value = (String) reqMap.get(key);
       if (StringUtil.isEmpty(value)) {
           // 必须字段为空，抛出异常
           if (must) {
               throwException(String.format("请求的参数[%s]不能为空", key));
           }
       } else {
           String regex = getGlobalParam(key, null);
           if (StringUtil.isEmpty(regex)) {
        	   log.info(String.format("【参数校验】%s字段无正则配置", key));
               return;
           }
           // 不符合正则表达式
           if (!value.matches(regex)) {
        	   log.info(String.format("Request Parameter %s[%s] cannot match the regex[%s]", key, value, regex));
               throwException(String.format("请求的参数[%s(%s)]格式或值不正确", key, value));
           }
       }
   }

   private static void throwException(String retMsg) throws BusinessException {
       throw new BusinessException(MerAccessEC.REQPARAM_ERR,retMsg);
   }

   private static String getGlobalParam(String key, String def) {
	   PropertyUtil propertyUtil = (PropertyUtil)SpringUtil.getBean("propertyUtil");
		// 找到这个服务需要校验哪些字段
	   String result = propertyUtil.getProperty(key);
       return StringUtil.isEmpty(result) ? def : result;
   }
}
